#include <stdio.h>
#include<stdbool.h>
#include<string.h>


//1


// int main()//函数的大括号中的代码构成复合语句
// {
// 	;//空语句
// 	int b;//没有赋值，不是赋值语句，不是表达式语句
// 	int a=3;//赋值语句，表达式语句一种
// 	b = a + 4;//运算符表达式语句
// 	printf("%d\n",b);
// 	printf("hehe\n");//函数调用语句
// 	_Bool flag = false;
// 	bool flag2 = true;
// 	if (flag)//条件判断是否执行语句，if判断假就不执行它
// 		printf("hello\n");
// 	if (flag2)
// 		printf("yes\n");
// 	int abc = 100;
// 		printf("%zd\n", sizeof(int));
// 		printf("%zd\n", sizeof abc);
// 		printf("%zd\n", sizeof 100);
// 		printf("%zd\n", sizeof 1000000);
// 		printf("%zd\n", sizeof(10.93));
// 		printf("%zd\n", sizeof(100.9));
// 		char d = "he";
// 		printf("%zd\n", sizeof(d));
// 		printf("%zd\n", sizeof 11);
// 		short s = 2;
// 		int f = 10;
// 		printf("%zd\n", sizeof(s = f + 1));//整型放到短整型里算的类型还是短整型
// 		printf("s= %d\n", s);
// 		unsigned int e = 0;
// 		printf("%d\n",e);
// 		unsigned int age = 10;//变量在创建时就给一个初始值，叫做初始化
// 		age = 20;//赋值
// 		float weight = 3.1f;
// 		double weight = 3.1;
// 	return 0;
// }


//2


// int main()
// {//字符数组里放的是字符串，用字符合成的字符字符串字符串末尾没有\0；这里是正常的有\0的
// 	char arr[6] = "abcdef";//{ "abcdef" }//err
// 	//字符数组初始化时，要么""全部字符堆里面，要么{}里面一个个''引的字符
// 	size_t len = strlen(arr);//用的库函数
// 	printf("%zd\n", len);
// 	//字符串本身自己的6个字符加上末尾加上来的'\0'共7个字符,如果是因为\0而多一个位置放不下的，不会报错，它会把\0前的就全放好，\0的就不放了，此时的字符串末尾没有\0，所以strlen搜索时会一直往后找记
// 	int lon = sizeof(arr);//算的是此数组类型的字节大小，它是字符类型的数组，开辟多少个元素空间该类型的大小就多少个字节，但不能用此算数组里字符的个数，因为开辟多少个元素空间不一定就等于放了多少个元素，可能没放满
// 	//而且sizeof算\0一个字节，而strlen算字符串里字符个数时不算\0
// 	//所以不能用sizeof算字符串里字符个数，要用strlen
// 	printf("%d\n", lon);
// 	return 0;
// }


//3


//int main()
//{
//	char a[] = { 'a','b','c' };//单些字符用数组合起来合成的字符串后面没有字符'\0'
//	printf("%s\n", a);
//	char b[3] = "abc";//"abc"字符串最后的一个字符'\0'没位置放就没放进去，%s搜索不到'\0'字符而不停地打印
//	printf("%s\n", b);
//	char c[] = "abc";//[]没值先不确定数组大小，等里面装完值才确定的数组大小
//	printf("%s\n", c);
//	int size = sizeof(c);
//	printf("%d\n", size);
//	int count = (sizeof(c) / sizeof(c[0]));
//	printf("%d\n", count);
//	return 0;
//}


//4 


// int main()
// {
// 	int a[] = { 1,2,3,4 };
// 	printf("%zd\n", sizeof(a));//16
// 	printf("%zd\n", sizeof(a + 0));//4/8  与sizeof(就数组名)不同
// 	printf("%zd\n", sizeof(*a));//4  *a -- *(a+0) -- a[0]
// 	printf("%zd\n", sizeof(a + 1));//4/8
// 	printf("%zd\n", sizeof(&a));//4/8  //地址都是头字节地址为载体，配合解引用权限表示是访问谁谁谁的地址
// 	printf("%zd\n", sizeof(a[1]));//4  //解引用权限地址性质是空的非载体
// 	printf("%zd\n", sizeof(*&a));//16
// 	printf("%zd\n", sizeof(&a + 1));//4/8
// 	printf("%zd\n", sizeof(&a[0]));//4/8
// 	printf("%zd\n", sizeof(&a[0] + 1));//4/8

// 	char arr[] = { 'a','b','c','d','e','f' };              //(%s)
// 	printf("%zd\n", strlen(arr));//随机值  //strlen对字符串，也识地址
// 	printf("%zd\n", strlen(arr + 0));//随机值  //可能字符串就是地址(字符数组首字符地址),%s、strlen都是识地址位置往后搜
// //err printf("%zd\n", strlen(*arr));  'a' - 97 ,传递给strlen后，strlen会认为97就是地址，然后去访问内存(未申请)
// //err printf("%zd\n", strlen(arr[1]));  'b' - 98 
// 	printf("%zd\n", strlen(&arr));//随机值
// 	printf("%zd\n", strlen(&arr + 1));//随机值，少算6个
// 	printf("%zd\n", strlen(&arr[0] + 1));//随机值，少算1个
// 	return 0;
// }

//int main()
//{//字符串就是字符数组首元素地址传给字符指针，q里面放的是数组首元素的地址但它不是数组名
//	char* q = "abf";
//	int* p = "abfg";//指针变量对头字节地址都是一样全接收
//	printf("%p\n", q);
//	printf("%p\n", p);
//	printf("\n");
//	                    //q不是数组名，它是个字符指针变量
//	printf("%zd\n", sizeof(q));//sizeof是看类型的,都是指针变量
//	printf("%zd\n", sizeof(p));//如果是sizeof(数组名)的话,就是数组类型
//	printf("\n");
//
//	printf("%zd\n", strlen(q));//解引用权限是1但strlen只看位置的
//	printf("%zd\n", strlen(p));
//	return 0;
//}

//int main()
//{
//	char* p = "abcdef";
//
//	printf("%zd\n", sizeof(p));//p是指针变量，计算的是指针变量p的大小，4/8个字节
//	printf("%zd\n", sizeof(p + 1));//p+1 是第二个元素的地址，地址的大小就是4/8个字节
//	printf("%zd\n", sizeof(*p));//p的类型是char*，所以*p只能访问一个字节
//	printf("%zd\n", sizeof(p[0]));//p[0] --> *(p+0) -- *p -- 1个字节
//	printf("%zd\n", sizeof(&p));//&p是指针变量p的地址，也是地址，是地址就是4/8个字节
//	//&p -- char* * -- 二级指针
//	printf("%zd\n", sizeof(&p + 1));//&p是p的地址，&p+1是跳过p变量，指向了p的后边
//	//&p+1是地址，就是4/8个字节
//	printf("%zd\n", sizeof(&p[0] + 1));//&p[0]+1就是b的地址
//	//&p[0] -- &*(p+0) -- a的地址
// 
//	return 0;
//}

////strlen只读成地址，有地址就能读，但要有意义的是读字符串那边有\0的
//int main()
//{
//	char* p = "abcdef";
//
//	printf("%zd\n", strlen(p));//6
//	printf("%zd\n", strlen(p + 1));//5
//	//printf("%zd\n", strlen(*p));//*p-'a'-97-程序奔溃
//	//printf("%zd\n",strlen(p[0]))//p[0] -- *(p+0) -- *p -- 程序奔溃
//	printf("%zd\n", strlen(&p));//随机值
//	printf("%zd\n", strlen(&p + 1));//随机值
//	printf("%zd\n", strlen(&p[0] + 1));//5
//
//	return 0;
//}

////二维数组里，a[0]成元素数组名名字了，成元素数组地址名即也是该元素数组首元素地址
//int main()
//{
//	int a[3][4] = { {1,2,3,4},{5,6,7,8},{9,10,11,12} };
//
//	printf("%zd\n", sizeof(a));//a是二维数组的数组名，单独放在sizeof内部，a表示的是整个二维数组，计算的是整个二维数组的大小，单位是字节 -- 48
//	printf("%zd\n", sizeof(a[0][0]));//a[0][0]是第一行第一个元素，大小是4个字节
//	printf("%zd\n", sizeof(a[0]));//a[0]是第一行的数组名，单独放在sizeof内部，计算的是数组的大小 4*4 = 16个字节
//	printf("%zd\n", sizeof(a[0] + 1));//a[0]是第一行的数组名，但是没有单独放在sizeof内部，那么只能是数组首元素的地址，那就是第一行第一个元素的地址 - &a[0][0]
//	//a[0]+1 == &a[0][0]+1 == &a[0][1]
//	//地址的大小 - 4/8
//	                       //a[0] -- 二维数组里的一维数组的数组名
//	printf("%zd\n", sizeof(*(a[0] + 1)));//是第一行第二个元素，大小是4个字节
//	                     //a -- 二维数组的数组名，是首元素即首元素数组地址，解引用权限就是这么大
//	printf("%zd\n", sizeof(a + 1));//a是二维数组的数组名，并没有单独放在sizeof内部，a表示首元素的地址-也就是第一行的地址
//	//a+1 是第二行的地址，是地址大小就是4/8个字节
//	printf("%zd\n", sizeof(*(a + 1)));
//	//1. *(a+1) -- a[1] -- 是第二行的数组名，单独放在sizeof内部，计算的是第二行的大小
//	//2. a+1是第二行的地址，类型是int(*)[4],数组指针，解引用访问的是这个数组，大小是16个字节//sizeof巧合在*(a+1)指向元素数组里的内容要改成元素数组数组名的意义时不改结果也对
//	//*(a+1)与a[1]在一维数组里它俩表现的内容都是数组里存的内容，等效转化的
//	//二维数组里，a[1]、*(a+1)意义都是元素数组数组名，元素数组首元素地址，也是等效转化的
//	printf("%zd\n", sizeof(&a[0] + 1));//a[0]是第一行的数组名，&数组名其实就是第一行的地址，&a[0]+1就是第二行的地址，是地址就是4/8
//	printf("%zd\n", sizeof(*(&a[0] + 1)));//16
//	//地址头都是数组首元素首字节地址，数组名是数组首元素地址，解引用权限为一个元素那么大，&数组名是该数组地址，解引用权限整个数组那么大
//	printf("%zd\n", sizeof(*a));//16
//	//1. a - 首元素的地址 (第一行的地址) , *a是第一行了
//	//2. *a -- *(a+0) -- a[0]
//	printf("%zd\n", sizeof(a[3]));//16
//	//sizeof内部的表达式是不会真实计算的，不会去访问第四行的，它是根据类型推断它的长度的
//	//a[3]- 第四行的数组名 int [4]
//
//	return 0;
//}

//int main()
//{
//	short s = 8;//2
//	int n = 12;//4   //这个表达式是不会去计算的
//	printf("%zd\n", sizeof(s = n + 5));
//	printf("%d\n", s);  //取决于左边
//	s = n + 5;
//	printf("%d\n", s);
//	return 0;
//}